package com.reactim.message.controller;

import com.reactim.common.response.Result;
import com.reactim.message.connection.ConnectionMonitoringService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.util.Map;

/**
 * 连接监控控制器
 * 提供连接监控和统计的REST API
 */
@RestController
@RequestMapping("/api/v1/monitoring")
@RequiredArgsConstructor
@Slf4j
public class ConnectionMonitoringController {

    private final ConnectionMonitoringService monitoringService;
    
    /**
     * 获取连接统计报告
     * 
     * @return 统计报告
     */
    @GetMapping("/statistics")
    public Mono<Result<Object>> getStatistics() {
        return Mono.just(Result.success(monitoringService.generateStatisticsReport()));
    }
    
    /**
     * 获取心跳状态
     * 
     * @return 心跳状态
     */
    @GetMapping("/heartbeat")
    public Mono<Result<Object>> getHeartbeatStatuses() {
        return Mono.just(Result.success(monitoringService.getHeartbeatStatuses()));
    }
    
    /**
     * 获取指定用户的心跳状态
     * 
     * @param userId 用户ID
     * @return 心跳状态
     */
    @GetMapping("/heartbeat/{userId}")
    public Mono<Result<Object>> getUserHeartbeatStatus(@PathVariable Long userId) {
        return Mono.just(Result.success(monitoringService.getUserHeartbeatStatus(userId)));
    }
    
    /**
     * 重置统计数据
     * 
     * @return 操作结果
     */
    @PostMapping("/statistics/reset")
    public Mono<Result<String>> resetStatistics() {
        monitoringService.resetStatistics();
        return Mono.just(Result.success("统计数据已重置"));
    }
    
    /**
     * 手动触发心跳检测
     * 
     * @return 操作结果
     */
    @PostMapping("/heartbeat/check")
    public Mono<Result<String>> triggerHeartbeatCheck() {
        monitoringService.performHeartbeatCheck();
        return Mono.just(Result.success("心跳检测已触发"));
    }
    
    /**
     * 获取实时连接统计数据流
     * 使用Server-Sent Events (SSE)提供实时数据
     * 
     * @return 统计数据流
     */
    @GetMapping(value = "/statistics/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<Object> getStatisticsStream() {
        return Flux.interval(Duration.ofSeconds(5))
                .map(tick -> monitoringService.generateStatisticsReport());
    }
    
    /**
     * 获取连接监控配置
     * 
     * @return 监控配置
     */
    @GetMapping("/config")
    public Mono<Result<Object>> getMonitoringConfig() {
        // 这里可以从ConnectionConfig中获取监控配置
        // 为简化实现，直接返回一个示例配置
        Map<String, Object> config = Map.of(
            "heartbeatIntervalMs", 30000,
            "inactivityThresholdMs", 300000,
            "autoRemoveInactive", true,
            "autoRemoveFailedHeartbeat", true,
            "sendActualHeartbeat", true,
            "reportIntervalMs", 60000,
            "enableEventLogging", true,
            "enableDashboard", true
        );
        
        return Mono.just(Result.success(config));
    }
    
    /**
     * 更新连接监控配置
     * 
     * @param config 监控配置
     * @return 操作结果
     */
    @PostMapping("/config")
    public Mono<Result<String>> updateMonitoringConfig(@RequestBody Map<String, Object> config) {
        // 这里可以更新ConnectionConfig中的监控配置
        // 为简化实现，仅记录日志
        log.info("收到监控配置更新请求: {}", config);
        return Mono.just(Result.success("监控配置已更新"));
    }
}